/**
 *
 * 添加标注
 *
 * @param     viewer          Mars3d实例对象
 * @param     color           标注颜色
 * @param     width           线条宽度
 * 
 * @function  DistanceMeasureTool           空间距离
 * @function  DistanceVertMeasureTool       垂直距离
 * @function  AngleMeasureTool              角度测量
 * @function  PolygonAreaTool               区域面积
 * @function  DistanceHorzMeasureTool       水平距离
 * 
 * @returns  BQGISToolManager
 *
 */

function markMap(string, value) {
  let map = string.split(","),
    i = 0,
    len = map.length,
    obj = {};
  for (i; i < len; i++) {
    obj[map[i]] = value;
    if (typeof value == "number") value++;
  }
  return obj;
}

function noop() {}

/**
 * 
 * @param {*} viewer  Mars3d实例对象
 * @param {*} color   标注颜色
 * @param {*} width   线条宽度
 * @returns 
 */
export function BQGISCreateToolManager(viewer, color, width) {
  let measure = new BQGISToolManager(viewer, color, width)
  return measure;
}

/**
 * @value viewer 
 * @value color    default #000000  默认黑色
 * @value width     default 1 默认1px
 */
let viewer,color="#000000",width=1
function BQGISToolManager(viewer, color, width) {
  this.viewer = viewer;
  this.color = color || "#000000";
  this.width = width || 1;
}
let emitEvent = "changeToolManager";
emitEvent = markMap(emitEvent, noop);
// 不允许自定义事件
BQGISToolManager.prototype.on = function on(type, call) {
  if (Reflect.has(emitEvent, type)) emitEvent[type] = call;
};

BQGISToolManager.prototype.emit = function emit(name, data) {
  if (Reflect.has(emitEvent, name))
    emitEvent[name]({
      type: name,
      target: data,
    });
};

let entitiesGlobal = []
BQGISToolManager.prototype.clear = function clear(){
  entitiesGlobal.forEach((e)=>{this.viewer.entities.remove(e)})
}
BQGISToolManager.prototype.destroyed = function destroyed() {
  this.viewer = null;
  this.color = null;
  this.width = null;
}
/**
 *  // 空间距离
    "distance"
    //垂直距离
    "heightVerticalStandard"
    //角度测量
    "triangle"
    //区域面积
    "computearea"
    //水平距离
    "horizontal"
 */
let MeasureType =
  "distance,heightVerticalStandard,triangle,computearea,horizontal";
MeasureType = markMap(MeasureType);
// 创建实体工具
BQGISToolManager.prototype.createToolManager = function createMeasure(type) {
  let number = typeof type == "string" ? MeasureType[type] : type;

  switch (number) {
    case 0:
      this.createDistanceMeasure();
      break;
    case 1:
      break;
    case 2:
      break;
    case 3:
      break;
    case 4:
      break;
    default:
      console.error(
        `not find ${type} in MeasureType:${Object.keys(
          MeasureType
        )} or ${Object.values(MeasureType)}`
      );
  }
};

let Primitive;
BQGISToolManager.prototype._createPrimitive = function createPrimitive(call) {
  if (Primitive) this.emit("changeMeasure", Primitive);
  Primitive = call(this.color,this.width);
};
// 空间距离
BQGISToolManager.prototype.DistanceMeasureTool = function DistanceMeasureTool() {
  let viewer = this.viewer;
  viewer.scene.globe.depthTestAgainstTerrain = false;
  viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(
    Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK
  );
  let entity;
  this._createPrimitive(function (color,width) {
    function _(positions) {
      this.options = {
        polyline: {
          //show: true,
          positions: [],
          material: color
            ? Cesium.Color.fromCssColorString(color)
            : Cesium.Color.GOLD,
          width: width ? width : 2.0,
          clampToGround: true,
        },
      };
      this.positions = positions;
      this._init();
    }

    _.prototype._init = function () {
      let _self = this;
      let _update = function () {
        return _self.positions;
      };
      //实时更新polyline.positions
      this.options.polyline.positions = new Cesium.CallbackProperty(
        _update,
        false
      );
      entity = viewer.entities.add(this.options);
    //   that.entityIds.push(entity.id);
    };
    return _;
  });
  // 坐标存储
  let positions = [];
  let handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
//   that.mapHandler = handler;
  let poly = undefined;
  // 鼠标左键单击画点
  let totalLength = 0;
  handler.setInputAction((movement) => {
    // 返回的生成的实体
    let entities = [];
    // debugger;
    let cartesian = viewer.scene.camera.pickEllipsoid(
      movement.position,
      viewer.scene.globe.ellipsoid
    );
    // let cartesian = viewer.scene.pickPosition(movement.position);
    if (positions.length == 0) {
      positions.push(cartesian.clone());

      entities.push(createLabel(cartesian, "起点", this.color, viewer));
    }
    positions.push(cartesian);

    entities.push(createPoint(cartesian, 5, this.color, viewer));

    if (positions.length >= 3) {
      let range = Cesium.Cartesian3.distance(
        positions[positions.length - 3],
        positions[positions.length - 1]
      );
      totalLength = totalLength + range;
      // 计算距离
      let lengthText =
        "本段距离：" +
        dataFormat(range.toFixed(3)) +
        ",  \r\n 距起点长度：" +
        dataFormat(totalLength);
      // 计算中点
      let centerPoint = Cesium.Cartesian3.midpoint(
        positions[positions.length - 2],
        positions[positions.length - 1],
        new Cesium.Cartesian3()
      );

      // 绘制距离长度标签
      let labelEntity = createLabel(
        centerPoint,
        lengthText,
        this.color,
        viewer
      );
      entities.push(labelEntity);
    }

    entitiesGlobal = entitiesGlobal.concat(entities)
    // call(entityId)

    // console.log("空间距离");
  }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
  // 注册鼠标移动事件
  handler.setInputAction(function (movement) {
    let cartesian = viewer.scene.camera.pickEllipsoid(
      movement.endPosition,
      viewer.scene.globe.ellipsoid
    );
    if (positions.length >= 2) {
      if (!Cesium.defined(poly)) {
        poly = new Primitive(positions);
      } else {
        if (cartesian != undefined) {
          positions.pop();
          // cartesian.y += (1 + Math.random());
          positions.push(cartesian);
        }
      }
    }
  }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

  //单击鼠标右键结束画点
  handler.setInputAction(function (movement) {
    positions.pop();
    handler.destroy();
    // that.active = "";
    // callback(positions);
  }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
};

//垂直距离
BQGISToolManager.prototype.DistanceVertMeasureTool =function DistanceVertMeasureTool() {
    let viewer = this.viewer;
    if (viewer.scene.mode === Cesium.SceneMode.SCENE2D) {
      viewer.scene.mode = Cesium.SceneMode.SCENE3D;
    }
    viewer.scene.globe.depthTestAgainstTerrain = true;
    viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(
      Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK
    );
    var entity;
    this._createPrimitive(function (color,width) {
      function _(positions) {
        this.options = {
          // parent: measure_entities,
          name: "直线",
          polyline: {
            show: true,
            positions: [],
            disableDepthTestDistance: 500000,
            material: new Cesium.PolylineDashMaterialProperty({
              color: Cesium.Color.BLUE, //线条颜色
              //gapColor: Cesium.Color.YELLOW,  //间隔颜色
              dashLength: 8.0, //短划线长度
            }),
            width: width ? width : 2,
          },
        };
        this.options1 = {
          polyline: {
            show: true,
            positions: [],
            disableDepthTestDistance: 500000,
            material: new Cesium.PolylineDashMaterialProperty({
              color: Cesium.Color.BLUE, //线条颜色
              //gapColor: Cesium.Color.YELLOW,  //间隔颜色
              dashLength: 8.0, //短划线长度
            }),
            width: width ? width : 2,
          },
        };
        this.options2 = {
          polyline: {
            //show: true,
            positions: [],
            disableDepthTestDistance: 500000,
            material: color
              ? Cesium.Color.fromCssColorString(color)
              : Cesium.Color.GOLD,
            width: width ? width : 2.0,
          },
        };
        this.positions = positions;
        this._init();
      }

      _.prototype._init = function () {
        var _self = this;
        var _update = function () {
          return _self.positions;
        };
        var _update1 = function () {
          var temp_position = [];
          //起点
          temp_position.push(_self.positions[0]);
          //组合终点（起点的经纬度加上终点的高度）
          var point_temp = pointHeight(_self.positions);
          temp_position.push(point_temp);
          return temp_position;
        };
        var _update2 = function () {
          var temp_position = [];
          //起点
          temp_position.push(_self.positions[1]);
          //组合终点（起点的经纬度加上终点的高度）
          var point_temp = pointHeight(_self.positions);
          temp_position.push(point_temp);
          return temp_position;
        };
        //实时更新polyline.positions
        this.options.polyline.positions = new Cesium.CallbackProperty(
          _update,
          false
        );
        this.options2.polyline.positions = new Cesium.CallbackProperty(
          _update1,
          false
        );
        this.options1.polyline.positions = new Cesium.CallbackProperty(
          _update2,
          false
        );
        let op1 = viewer.entities.add(this.options);
        let op2 = viewer.entities.add(this.options1);
        let op3 = viewer.entities.add(this.options2);
        // that.entityIds.push(op1.id);
        // that.entityIds.push(op2.id);
        // that.entityIds.push(op3.id);
      };

      return _;
    });

    function pointHeight(_positions) {
      var point1cartographic = Cesium.Cartographic.fromCartesian(_positions[0]); //起点
      var point2cartographic = Cesium.Cartographic.fromCartesian(_positions[1]); //终点
      //组合终点（起点的经纬度加上终点的高度）
      var point_temp = Cesium.Cartesian3.fromDegrees(
        Cesium.Math.toDegrees(point1cartographic.longitude),
        Cesium.Math.toDegrees(point1cartographic.latitude),
        point2cartographic.height
      );
      return point_temp;
    }

    //平面两点垂直距离计算函数
    function getHeight(_positions) {
      var cartographic = Cesium.Cartographic.fromCartesian(_positions[0]);
      var cartographic1 = Cesium.Cartographic.fromCartesian(_positions[1]);
      var height_temp = cartographic1.height - cartographic.height;
      return height_temp.toFixed(2);
    }
    var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
    // that.mapHandler = handler;
    var positions = [];
    var poly = undefined;
    var height = 0;
    //鼠标左键单击画点
    handler.setInputAction((movement) => {
      // 返回的生成的实体
      let entities = [];

      let cartesian = viewer.scene.pickPosition(movement.position);
      if (positions.length == 0) {
        positions.push(cartesian.clone());
        //添加起始点图标
        entities.push(createPoint(cartesian, 5, "RED",viewer));
      }
      positions.push(cartesian);
      if (positions.length > 2) {
        handler.destroy();
        // that.active = "";
        height = getHeight(positions);
        var textDisance = dataFormat(height);
        var point_temp = pointHeight(positions);
        entities.push(createPoint(point_temp, 5, "RED",viewer));
        entities.push(createLabel(point_temp, textDisance,this.color,viewer));
        viewer.scene.globe.depthTestAgainstTerrain = false;
      }
      entitiesGlobal = entitiesGlobal.concat(entities)
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
    //鼠标移动
    handler.setInputAction((movement) => {
      var cartesian = viewer.scene.pickPosition(movement.endPosition);
      if (positions.length >= 2) {
        if (!Cesium.defined(poly)) {
          poly = new Primitive(positions);
        } else {
          if (cartesian != undefined) {
            positions.pop();
            // cartesian.y += (1 + Math.random());
            positions.push(cartesian);
          }
        }
      }
    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

    //单击鼠标右键结束画线
    // handler.setInputAction((movement) => {
    //   handler.destroy();
    //   var textDisance = this.dataFormat(height);
    //   var point1cartographic = Cesium.Cartographic.fromCartesian(
    //     positions[0]
    //   );
    //   var point2cartographic = Cesium.Cartographic.fromCartesian(
    //     positions[1]
    //   );
    //   var point_temp = Cesium.Cartesian3.fromDegrees(
    //     Cesium.Math.toDegrees(point1cartographic.longitude),
    //     Cesium.Math.toDegrees(point1cartographic.latitude),
    //     point2cartographic.height
    //   );
    //   this.createPoint(point_temp, 5, "RED");
    //   this.createLabel(point_temp, textDisance);
    //   that.active = "";
    //   viewer.scene.globe.depthTestAgainstTerrain = false;
    // }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
  };

//角度测量
BQGISToolManager.prototype.AngleMeasureTool = function AngleMeasureTool() {
  let that = this;
  let viewer = this.viewer;
  viewer.scene.globe.depthTestAgainstTerrain = false;
  viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(
    Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK
  );
  var entity;
  
  this._createPrimitive(function (color,width) {
    function _(positions) {
      this.options = {
        polyline: {
          //show: true,
          positions: [],
          material: color
            ? Cesium.Color.fromCssColorString(color)
            : Cesium.Color.GOLD,
          width: width ? width : 2.0,
          clampToGround: true,
        },
      };
      this.positions = positions;
      this._init();
    }

    _.prototype._init = function () {
      var _self = this;
      var _update = function () {
        return _self.positions;
      };
      //实时更新polyline.positions
      this.options.polyline.positions = new Cesium.CallbackProperty(
        _update,
        false
      );
      entity = viewer.entities.add(this.options);
    //   that.entityIds.push(entity.id);
    };
    return _;
  })

  var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
//   that.mapHandler = handler;
  var positions = [];
  var poly = undefined;
  //鼠标左键单击画点
  handler.setInputAction((movement) => {
    // 返回的生成的实体
    let entities = [];
    var cartesian = viewer.scene.camera.pickEllipsoid(
      movement.position,
      viewer.scene.globe.ellipsoid
    );
    if (positions.length == 0) {
      positions.push(cartesian.clone());
    }
    positions.push(cartesian);
    if (positions.length >= 4) {
      handler.destroy();
    //   that.active = "";
      var anglerLabel;
      if (
        positions[1].x == positions[2].x &&
        positions[1].y == positions[2].y
      ) {
        anglerLabel = "0度";
      } else {
        anglerLabel = calcAngler(positions).toFixed(2) + "度";
      }
      entities.push(createLabel(positions[1], anglerLabel,this.color,viewer));
    }
    entitiesGlobal = entitiesGlobal.concat(entities)
  }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

  //鼠标移动
  handler.setInputAction((movement) => {
    var cartesian = viewer.scene.camera.pickEllipsoid(
      movement.endPosition,
      viewer.scene.globe.ellipsoid
    );
    if (positions.length >= 2) {
      if (!Cesium.defined(poly)) {
        poly = new Primitive(positions);
      } else {
        if (cartesian != undefined) {
          positions.pop();
          // cartesian.y += (1 + Math.random());
          positions.push(cartesian);
        }
      }
    }
  }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

  //单击鼠标右键结束画线
  handler.setInputAction(function (movement) {
    handler.destroy();
    // callback(positions);
    // that.active = "";
  }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);

  // 计算三点的夹角
  function calcAngler(points) {
    const v1 = Cesium.Cartesian3.subtract(
      points[0],
      points[1],
      new Cesium.Cartesian3()
    );
    const v2 = Cesium.Cartesian3.subtract(
      points[2],
      points[1],
      new Cesium.Cartesian3()
    );
    const vn1 = Cesium.Cartesian3.normalize(v1, new Cesium.Cartesian3());
    const vn2 = Cesium.Cartesian3.normalize(v2, new Cesium.Cartesian3());
    const ac = Cesium.Cartesian3.dot(vn1, vn2);
    const angle = Cesium.Math.acosClamped(ac);
    return (angle * 180.0) / Math.PI;
  }

  function coordPosition(position) {
    return Cesium.Cartesian3.fromDegrees(position.x, position.y);
  }
};

//区域面积
BQGISToolManager.prototype.PolygonAreaTool = function PolygonAreaTool() {
  let that = this;
  let viewer = this.viewer;
  let entities = [];
  viewer.scene.globe.depthTestAgainstTerrain = false;

  this._createPrimitive(function (color,width) {
    function _(positions) {
      this.options = {
        name: "多边形",
        polygon: {
          hierarchy: [],
          // perPositionHeight : true,
          material: Cesium.Color.GREEN.withAlpha(0.5),
          // heightReference:20000
        },
      };

      this.hierarchy = { positions };
      this._init();
    }

    _.prototype._init = function () {
      var _self = this;
      var _update = function () {
        return _self.hierarchy;
      };
      //实时更新polygon.hierarchy
      this.options.polygon.hierarchy = new Cesium.CallbackProperty(
        _update,
        false
      );
      let opt = viewer.entities.add(this.options);
      //   that.entityIds.push(opt.id);
      entities.push(opt);
      entitiesGlobal = entitiesGlobal.concat(entities)
    };

    return _;
  })

  var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
//   that.mapHandler = handler;
  // 取消双击事件-追踪该位置
  viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(
    Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK
  );
  // 鼠标事件
  // handler = new Cesium.ScreenSpaceEventHandler(
  //   viewer.scene._imageryLayerCollection
  // );

  var positions = [];
  var tempPoints = [];
  var polygon = null;
  // var cartesian = null;
  var floatingPoint; //浮动点

  handler.setInputAction((movement) => {
    // let ray = viewer.camera.getPickRay(
    //   new Cesium.Cartesian2(
    //     movement.endPosition.x,
    //     movement.endPosition.y - 120
    //   )
    // );
    // cartesian = viewer.scene.globe.pick(ray, viewer.scene);
    let cartesian = viewer.scene.camera.pickEllipsoid(
      movement.endPosition,
      viewer.scene.globe.ellipsoid
    );
    if (positions.length >= 2) {
      if (!Cesium.defined(polygon)) {
        polygon = new Primitive(positions);
      } else {
        positions.pop();
        positions.push(cartesian);
      }
    }
  }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

  handler.setInputAction((movement) => {
    // let ray = viewer.camera.getPickRay(
    //   new Cesium.Cartesian2(movement.position.x, movement.position.y - 120)
    // );
    // cartesian = viewer.scene.globe.pick(ray, viewer.scene);
    let cartesian = viewer.scene.camera.pickEllipsoid(
      movement.position,
      viewer.scene.globe.ellipsoid
    );
    if (positions.length == 0) {
      positions.push(cartesian.clone());
    }
    //positions.pop();
    positions.push(cartesian);
    //在三维场景中添加点
    var cartographic = Cesium.Cartographic.fromCartesian(
      positions[positions.length - 1]
    );
    var longitudeString = Cesium.Math.toDegrees(cartographic.longitude);
    var latitudeString = Cesium.Math.toDegrees(cartographic.latitude);
    var heightString = cartographic.height;
    tempPoints.push({
      lon: longitudeString,
      lat: latitudeString,
      hei: heightString,
    });
    floatingPoint = viewer.entities.add({
      name: "多边形面积",
      position: positions[positions.length - 1],
      point: {
        pixelSize: 5,
        color: Cesium.Color.RED,
        outlineColor: Cesium.Color.WHITE,
        outlineWidth: 2,
        heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
      },
    });
    // that.entityIds.push(floatingPoint.id);
    entities.push(floatingPoint);
    entitiesGlobal = entitiesGlobal.concat(entities)
  }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

  handler.setInputAction((movement) => {
    var sum_x = 0.0;
    var sum_y = 0.0;
    var sum_z = 0.0;
    for (var i = 0; i < tempPoints.length; i++) {
      sum_x += Number(tempPoints[i].lon);
      sum_y += Number(tempPoints[i].lat);
      sum_z += Number(tempPoints[i].hei);
    }
    var avg_x = sum_x / tempPoints.length;
    var avg_y = sum_y / tempPoints.length;
    var avg_z = sum_z / tempPoints.length;
    handler.destroy();
    positions.pop();
    var textArea = getArea(tempPoints) + "平方公里";
    let polygon = viewer.entities.add({
      name: "多边形面积",
      //position: positions[positions.length - 1],
      position: Cesium.Cartesian3.fromDegrees(avg_x, avg_y),
      label: {
        text: textArea,
        font: "14px sans-serif",
        fillColor: Cesium.Color.SNOW,
        style: Cesium.LabelStyle.FILL_AND_OUTLINE,
        outlineWidth: 2,
        verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
        pixelOffset: new Cesium.Cartesian2(20, -40),
        heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
        showBackground: true,
        scale: 1,
        horizontalOrigin: Cesium.HorizontalOrigin.LEFT,
        disableDepthTestDistance: Number.POSITIVE_INFINITY,
        distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
          1.0,
          10000000.0
        ),
      },
    });
    // that.entityIds.push(polygon.id);
    entities.push(polygon);
    entitiesGlobal = entitiesGlobal.concat(entities)
    // that.active = "";
  }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);

  var radiansPerDegree = Math.PI / 180.0; //角度转化为弧度(rad)
  var degreesPerRadian = 180.0 / Math.PI; //弧度转化为角度

  //计算多边形面积
  function getArea(points) {
    var res = 0;
    //拆分三角曲面

    for (var i = 0; i < points.length - 2; i++) {
      var j = (i + 1) % points.length;
      var k = (i + 2) % points.length;
      var totalAngle = Angle(points[i], points[j], points[k]);

      var dis_temp1 = distance(positions[i], positions[j]);
      var dis_temp2 = distance(positions[j], positions[k]);
      res += dis_temp1 * dis_temp2 * Math.abs(Math.sin(totalAngle));
      // console.log(res);
    }

    return (res / 1000000.0).toFixed(4);
  }

  /*角度*/
  function Angle(p1, p2, p3) {
    var bearing21 = Bearing(p2, p1);
    var bearing23 = Bearing(p2, p3);
    var angle = bearing21 - bearing23;
    if (angle < 0) {
      angle += 360;
    }
    return angle;
  }
  /*方向*/
  function Bearing(from, to) {
    var lat1 = from.lat * radiansPerDegree;
    var lon1 = from.lon * radiansPerDegree;
    var lat2 = to.lat * radiansPerDegree;
    var lon2 = to.lon * radiansPerDegree;
    var angle = -Math.atan2(
      Math.sin(lon1 - lon2) * Math.cos(lat2),
      Math.cos(lat1) * Math.sin(lat2) -
        Math.sin(lat1) * Math.cos(lat2) * Math.cos(lon1 - lon2)
    );
    if (angle < 0) {
      angle += Math.PI * 2.0;
    }
    angle = angle * degreesPerRadian; //角度
    return angle;
  }

  function distance(point1, point2) {
    var point1cartographic = Cesium.Cartographic.fromCartesian(point1);
    var point2cartographic = Cesium.Cartographic.fromCartesian(point2);
    /**根据经纬度计算出距离**/
    var geodesic = new Cesium.EllipsoidGeodesic();
    geodesic.setEndPoints(point1cartographic, point2cartographic);
    var s = geodesic.surfaceDistance;
    //console.log(Math.sqrt(Math.pow(distance, 2) + Math.pow(endheight, 2)));
    //返回两点之间的距离
    s = Math.sqrt(
      Math.pow(s, 2) +
        Math.pow(point2cartographic.height - point1cartographic.height, 2)
    );
    return s;
  }
};

//水平距离
BQGISToolManager.prototype.DistanceHorzMeasureTool = function DistanceHorzMeasureTool() {
  let that = this;
  let viewer = this.viewer;
  if (viewer.scene.mode === Cesium.SceneMode.SCENE2D) {
    viewer.scene.mode = Cesium.SceneMode.SCENE3D;
  }

  viewer.scene.globe.depthTestAgainstTerrain = true;
  viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(
    Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK
  );
  var entity;
  this._createPrimitive(function (color,width) {
    function _(positions) {
      // console.log(this,"createHorizontal")
      this.options = {
        // parent: measure_entities,
        name: "直线",
        polyline: {
          show: true,
          positions: [],
          disableDepthTestDistance: 500000,
          heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, //贴地
          material: new Cesium.PolylineDashMaterialProperty({
            color: Cesium.Color.BLUE, //线条颜色
            //gapColor: Cesium.Color.YELLOW,  //间隔颜色
            dashLength: 8.0, //短划线长度
          }),
          width: width ? width : 2,
        },
      };
      this.options1 = {
        polyline: {
          show: true,
          positions: [],
          disableDepthTestDistance: 500000,
          heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, //贴地
          material: new Cesium.PolylineDashMaterialProperty({
            color: Cesium.Color.BLUE, //线条颜色
            //gapColor: Cesium.Color.YELLOW,  //间隔颜色
            dashLength: 8.0, //短划线长度
          }),
          width: width ? width : 2,
        },
      };
      this.options2 = {
        polyline: {
          //show: true,
          positions: [],
          disableDepthTestDistance: 500000,
          heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, //贴地
          material: color
            ? Cesium.Color.fromCssColorString(color)
            : Cesium.Color.GOLD,
          width: width ? width : 2.0,
        },
      };
      this.positions = positions;
      this._init();
    }

    _.prototype._init = function () {
      var _self = this;
      var _update = function () {
        return _self.positions;
      };
      var _update1 = function () {
        var temp_position = [];
        //起点
        temp_position.push(_self.positions[0]);
        //组合终点（起点的经纬度加上终点的高度）
        var point_temp = pointHeight(_self.positions);
        temp_position.push(point_temp);
        return temp_position;
      };
      var _update2 = function () {
        var temp_position = [];
        //起点
        temp_position.push(_self.positions[1]);
        //组合终点（起点的经纬度加上终点的高度）
        var point_temp = pointHeight(_self.positions);
        temp_position.push(point_temp);
        return temp_position;
      };
      //实时更新polyline.positions
      this.options.polyline.positions = new Cesium.CallbackProperty(
        _update,
        false
      );
      this.options2.polyline.positions = new Cesium.CallbackProperty(
        _update2,
        false
      );
      this.options1.polyline.positions = new Cesium.CallbackProperty(
        _update1,
        false
      );
      let op1 = viewer.entities.add(this.options);
      let op2 = viewer.entities.add(this.options1);
      let op3 = viewer.entities.add(this.options2);
    //   that.entityIds.push(op1.id);
    //   that.entityIds.push(op2.id);
    //   that.entityIds.push(op3.id);
    };

    return _;
  })
  function pointHeight(_positions) {
    var point1cartographic = Cesium.Cartographic.fromCartesian(_positions[0]); //起点
    var point2cartographic = Cesium.Cartographic.fromCartesian(_positions[1]); //终点
    //组合终点（起点的经纬度加上终点的高度）
    var point_temp = Cesium.Cartesian3.fromDegrees(
      Cesium.Math.toDegrees(point1cartographic.longitude),
      Cesium.Math.toDegrees(point1cartographic.latitude),
      point2cartographic.height
    );
    return point_temp;
  }

  //平面两点垂直距离计算函数
  function getHeight(_positions) {
    var cartographic = Cesium.Cartographic.fromCartesian(_positions[0]);
    var cartographic1 = Cesium.Cartographic.fromCartesian(_positions[2]);
    //var cartographic1 = Cesium.Cartographic.fromCartesian(_positions[1]);
    var height_temp = cartographic1.height - cartographic.height;
    return height_temp.toFixed(2);
  }
  var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
  // that.mapHandler = handler;
  var positions = [];
  var poly = undefined;
  var disance = 0;
  // measureHeight(viewer, handler);
  // measureLineFlat(viewer, 5);
  //鼠标左键单击画点
  handler.setInputAction((movement) => {
    let cartesian = viewer.scene.pickPosition(movement.position);
    if (positions.length == 0) {
      positions.push(cartesian.clone());
      //添加起始点图标
      // this.createPoint(cartesian, 5, "RED");
    }
    positions.push(cartesian);
    if (positions.length > 2) {
      handler.destroy();
      createPoint(cartesian, 5, "RED",viewer);

      disance = Cesium.Cartesian3.distance(
        positions[positions.length - 3],
        positions[positions.length - 1]
      ).toFixed(2); //getHeight(positions);
      var textDisance = dataFormat(disance);
      var point_temp = pointHeight(positions);
      createPoint(point_temp, 5, "RED",viewer);
      createLabel(point_temp, textDisance,this.color,viewer);
    //   that.active = "";
      viewer.scene.globe.depthTestAgainstTerrain = false;
    }
  }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
  //鼠标移动
  handler.setInputAction((movement) => {
    var cartesian = viewer.scene.pickPosition(movement.endPosition);
    if (positions.length >= 2) {
      if (!Cesium.defined(poly)) {
        poly = new Primitive(positions);
      } else {
        if (cartesian != undefined) {
          positions.pop();
          // cartesian.y += (1 + Math.random());
          positions.push(cartesian);
        }
      }
    }
  }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
};

/**
 * 创建label 类中私有 方法
 * @param {*} position 
 * @param {*} name 
 * @param {*} color 
 * @param {*} viewer 
 * @returns 
 */
function createLabel(position, name, color, viewer) {
  var label = viewer.entities.add({
    position: position,
    label: {
      text: name,
      font: "14px MicroSoft YaHei",
      show: true,
      fillColor: color
        ? Cesium.Color.fromCssColorString(color)
        : Cesium.Color.SNOW,
      showBackground: true,
      outlineWidth: 1,
      // fillColor: new Cesium.Color(164, 211, 238, 50),
      scale: 1,
      horizontalOrigin: Cesium.HorizontalOrigin.LEFT,
      // horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
      verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
      disableDepthTestDistance: Number.POSITIVE_INFINITY,
      distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
        1.0,
        10000000.0
      ),
    },
  });
  // entitiesGlobal.push(label);
  return label;
}
/**
 * 创建标点 类中私有方法
 * @param {*} position 
 * @param {*} size 
 * @param {*} color 
 * @param {*} viewer 
 * @returns 
 */
function createPoint(position, size, color, viewer) {
  var pointGeometry = viewer.entities.add({
    name: "点几何对象",
    position: position,
    point: {
      color: color
        ? new Cesium.Color.fromCssColorString(color)
        : Cesium.Color.RED,
      pixelSize: size,
    },
  });
  // this.entityIds.push(pointGeometry.id);
  // entitiesGlobal.push(label);
  return pointGeometry;
}
/**
 * 数据格式化  类中私有 方法
 * @param {*} data 
 * @returns 
 */
function dataFormat(data) {
  if (Number.parseInt(data) > 10000) {
    data = (data / 1000).toFixed(2) + "千米";
  } else {
    data = (data * 1).toFixed(2) + "米";
  }
  return data;
}